package cc.comac.mom.datahandlers.timer;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cc.comac.mom.bean.EquipPatrolCheckWorkOrder;
import cc.comac.mom.dao.entity.EquipPatrolCheckPlanDao;
import cc.comac.mom.datahandlers.entity.EquipPatrolCheckWorkOrderDataHandler;
import cc.comac.mom.entity.EquipPatrolCheckPlanEntity;
import cc.comac.mom.entity.EquipPatrolCheckWorkOrderEntity;
import cc.comac.mom.redis.IdFactory;
import cc.comac.mom.util.BaseEntityDataUtil;
import cc.comac.mom.util.MomConstants;
import cc.comac.mom.util.TimeUtil;

/**
 * 巡检计划定时发布
* @ClassName: EquipPatrolCheckPlanScheduled  
* @Description: TODO  
* @author FYT  
* @date 2020年9月4日 上午9:26:11  
*
 */
@Component
public class EquipPatrolCheckPlanScheduled extends ServiceImpl<EquipPatrolCheckPlanDao, EquipPatrolCheckPlanEntity> {
	@Autowired
	private EquipPatrolCheckPlanDao equipPatrolCheckPlanDao;

	@Autowired 
	private EquipPatrolCheckWorkOrderDataHandler equipPatrolCheckWorkOrderDataHandler;
	@Autowired
	private BaseEntityDataUtil baseEntityDataUtil;
	
	@Resource
	private IdFactory idFactory;
	
	@Transactional
	@Scheduled(cron = "0 0 1 * * ?")//每天凌晨一点触发
	@Async
	public void autoPlanIssue() {
    	QueryWrapper<EquipPatrolCheckPlanEntity> queryWrapper = new QueryWrapper<EquipPatrolCheckPlanEntity>();
    	queryWrapper.eq("row_status",1);
    	queryWrapper.eq("status",MomConstants.EQUIP_REGULAR_CHECK_PLAN_STATUS_ISSUED);//已发布
    	queryWrapper.eq("is_expire",0);//未过期
    	List<EquipPatrolCheckPlanEntity> selectList = equipPatrolCheckPlanDao.selectList(queryWrapper);
    	if(selectList != null && selectList.size()>0) {
    		ArrayList<EquipPatrolCheckWorkOrder> listEquipPatrolCheckWorkOrder = new  ArrayList<EquipPatrolCheckWorkOrder>();
    		ArrayList<EquipPatrolCheckPlanEntity> listEntity = new ArrayList<EquipPatrolCheckPlanEntity>();
    		
    		for(EquipPatrolCheckPlanEntity item :selectList) {

    			//计算下一个工单的开始日期
    			   //频率小时
    			int frequent = this.getCycleDataToHouse(item.getFrequentType(), item.getFrequentValue());
    			   //执行时长
    			int executionHours = this.getCycleDataToHouse(item.getExecutionTime(), item.getExecutionTimeValue());
    			
    			//周期结束日期
    			LocalDateTime cycleDataToDateTime = this.getCycleDataToDateTime(item.getCycle(), item.getCycleValue(),TimeUtil.fomatDateToLocalDateTime(item.getFirstPlanStartDate()));
    			//下一次开始日期
    			LocalDateTime nextPlanStartData = TimeUtil.fomatDateToLocalDateTime(item.getPlanStartDate()).plusHours(frequent);
    			//当前时间
    			LocalDateTime now = LocalDateTime.now();
    			if(cycleDataToDateTime.isBefore(nextPlanStartData)) {
    				//下次日期超过周期结束日期，说明已过期
    				item.setIsExpire(1);//已过期
    				listEntity.add(item);
    				continue;
    			}
    			
    			if(now.toLocalDate().equals(nextPlanStartData.toLocalDate())&& item.getIsAlendar() == 0) {
    				//说明今天应该生成工单日,且不用考虑工作日历
    				EquipPatrolCheckWorkOrder equipPatrolCheckWorkOrder = new EquipPatrolCheckWorkOrder();
    				EquipPatrolCheckWorkOrderEntity equipPatrolCheckWorkOrderEntity = new EquipPatrolCheckWorkOrderEntity();
    				equipPatrolCheckWorkOrderEntity.setWorkNumber(idFactory.generateEquipPatrolCheckPlanOrderNo());
    				equipPatrolCheckWorkOrderEntity.setPatrolCheckId(item.getId());
    				equipPatrolCheckWorkOrderEntity.setDescription(item.getDescription());
    				equipPatrolCheckWorkOrderEntity.setPlanNumber(item.getPlanNumber());
    				equipPatrolCheckWorkOrderEntity.setFrequentType(item.getFrequentType());
    				equipPatrolCheckWorkOrderEntity.setFrequentValue(item.getFrequentValue());
    				equipPatrolCheckWorkOrderEntity.setCycle(item.getCycle());
    				equipPatrolCheckWorkOrderEntity.setCycleValue(item.getCycleValue());
    				equipPatrolCheckWorkOrderEntity.setExecuteUser(item.getExecuteUser());
    				equipPatrolCheckWorkOrderEntity.setIsAlendar(item.getIsAlendar());
    				equipPatrolCheckWorkOrderEntity.setCalendarCode(item.getCalendarCode());
    				equipPatrolCheckWorkOrderEntity.setPlanStartDate(item.getFirstPlanStartDate());
    				equipPatrolCheckWorkOrderEntity.setPlanEndDate(TimeUtil.fomatLocalDateTimeToDate(TimeUtil.fomatDateToLocalDateTime(item.getFirstPlanStartDate()).plusHours(executionHours)));
    				equipPatrolCheckWorkOrderEntity.setLocation(item.getLocation());
    				equipPatrolCheckWorkOrderEntity.setStatus(MomConstants.EQUIP_REGULAR_CHECK_ORDER_STATUS_NOEXECUTE);//待执行
    				equipPatrolCheckWorkOrder.setInnerData(equipPatrolCheckWorkOrderEntity);
    				listEquipPatrolCheckWorkOrder.add(equipPatrolCheckWorkOrder);
    				
    				item.setPlanStartDate(TimeUtil.fomatLocalDateTimeToDate(nextPlanStartData));
    				item.setPlanEndDate(TimeUtil.fomatLocalDateTimeToDate(nextPlanStartData.plusHours(executionHours)));
    				listEntity.add(item);
    				
    				continue;
    			}
    			if(now.toLocalDate().equals(nextPlanStartData.toLocalDate())&& item.getIsAlendar() != 0) {
    				//说明今天应该生成工单日,且要考虑工作日历
    				//预留接口
    				continue;
    			}
    			
    			if(now.toLocalDate().isBefore(nextPlanStartData.toLocalDate())){
    				//说明今天不应该生成工单
    				continue;
    			}
    			if(now.toLocalDate().isAfter(nextPlanStartData.toLocalDate())) {
    				//说明今天已经超过了下次应该生成的日期
    				for(int i= 0;i<10000;i++) {
    					nextPlanStartData = nextPlanStartData.plusHours(frequent);  					
    	    			if(cycleDataToDateTime.isBefore(nextPlanStartData)) {
    	    				//下次日期超过周期结束日期，说明已过期
    	    				item.setIsExpire(1);//已过期
    	    				listEntity.add(item);
    	    				break;
    	    			}
    	    			if(now.toLocalDate().equals(nextPlanStartData.toLocalDate())&& item.getIsAlendar() == 0) {
    	    				//说明今天应该生成工单日,且不用考虑工作日历
    	    				EquipPatrolCheckWorkOrder equipPatrolCheckWorkOrder = new EquipPatrolCheckWorkOrder();
    	    				EquipPatrolCheckWorkOrderEntity equipPatrolCheckWorkOrderEntity = new EquipPatrolCheckWorkOrderEntity();
    	    				equipPatrolCheckWorkOrderEntity.setWorkNumber(idFactory.generateEquipPatrolCheckPlanOrderNo());
    	    				equipPatrolCheckWorkOrderEntity.setPatrolCheckId(item.getId());
    	    				equipPatrolCheckWorkOrderEntity.setDescription(item.getDescription());
    	    				equipPatrolCheckWorkOrderEntity.setPlanNumber(item.getPlanNumber());
    	    				equipPatrolCheckWorkOrderEntity.setFrequentType(item.getFrequentType());
    	    				equipPatrolCheckWorkOrderEntity.setFrequentValue(item.getFrequentValue());
    	    				equipPatrolCheckWorkOrderEntity.setCycle(item.getCycle());
    	    				equipPatrolCheckWorkOrderEntity.setCycleValue(item.getCycleValue());
    	    				equipPatrolCheckWorkOrderEntity.setExecuteUser(item.getExecuteUser());
    	    				equipPatrolCheckWorkOrderEntity.setIsAlendar(item.getIsAlendar());
    	    				equipPatrolCheckWorkOrderEntity.setCalendarCode(item.getCalendarCode());
    	    				equipPatrolCheckWorkOrderEntity.setPlanStartDate(item.getFirstPlanStartDate());
    	    				equipPatrolCheckWorkOrderEntity.setPlanEndDate(TimeUtil.fomatLocalDateTimeToDate(TimeUtil.fomatDateToLocalDateTime(item.getFirstPlanStartDate()).plusHours(executionHours)));
    	    				equipPatrolCheckWorkOrderEntity.setLocation(item.getLocation());
    	    				equipPatrolCheckWorkOrderEntity.setCreator(item.getCreator());
    	    				equipPatrolCheckWorkOrderEntity.setLastModifier(item.getLastModifier());
    	    				equipPatrolCheckWorkOrderEntity.setStatus(MomConstants.EQUIP_REGULAR_CHECK_ORDER_STATUS_NOEXECUTE);//待执行
    	    				equipPatrolCheckWorkOrder.setInnerData(equipPatrolCheckWorkOrderEntity);
    	    				listEquipPatrolCheckWorkOrder.add(equipPatrolCheckWorkOrder);
    	    				
    	    				item.setPlanStartDate(TimeUtil.fomatLocalDateTimeToDate(nextPlanStartData));
    	    				item.setPlanEndDate(TimeUtil.fomatLocalDateTimeToDate(nextPlanStartData.plusHours(executionHours)));
    	    				listEntity.add(item);
    	    				
    	    				break;
    	    			}
    	    			if(now.toLocalDate().equals(nextPlanStartData.toLocalDate())&& item.getIsAlendar() != 0) {
    	    				//说明今天应该生成工单日,且要考虑工作日历
    	    				//预留接口
    	    				break;
    	    			}
    	    			if(now.toLocalDate().isBefore(nextPlanStartData.toLocalDate())) {
    	    				//说明今天不应该生成工单
    	    				break;
    	    			}
    	    			if(now.toLocalDate().isAfter(nextPlanStartData.toLocalDate())) {
    	    				//继续执行循环
    	    				continue;
    	    			}
    				}
    				continue;
    			}
    			
    		}
    		if(listEntity != null &&listEntity.size()>0) {
    			for(EquipPatrolCheckPlanEntity item2:listEntity) {
    				item2.setLastModifiedTime(TimeUtil.getLocalDateTime());
    				item2.setLastModifiedTimeZone(TimeUtil.getLocalTimeZone());
//    				baseEntityDataUtil.updateBaseEntityData(item2);
    			}
    			//批量修改巡检计划信息
    			this.updateBatchById(listEntity);
    		}
    		if(listEquipPatrolCheckWorkOrder != null && listEquipPatrolCheckWorkOrder.size()>0) {
    			//批量生成巡检计划工单
    			equipPatrolCheckWorkOrderDataHandler.insertBatch(listEquipPatrolCheckWorkOrder);
    		}
    	}
	}
	
	// 通过计划首次开始时间和循环周期算出结束时间
	public LocalDateTime getCycleDataToDateTime(String unit,int cycleValue, LocalDateTime firstPlanDateStart) {
		LocalDateTime dateTime = null;
		switch (unit) {
		case "hour":
			dateTime = firstPlanDateStart.plusHours(cycleValue);
			break;
		case "day":
			dateTime = firstPlanDateStart.plusDays(cycleValue);
			break;
		case "week":
			dateTime = firstPlanDateStart.plusDays(cycleValue * 7);
			break;
		case "month":
			dateTime = firstPlanDateStart.plusMonths(cycleValue);
			break;
		case "quarter":
			dateTime = firstPlanDateStart.plusMonths(cycleValue * 3);
			break;
		case "year":
			dateTime = firstPlanDateStart.plusYears(cycleValue);
			break;
		default:
			throw new RuntimeException("传入数据无法转换时间！");
		}
		return dateTime;
	}

	// 将1周、1月等数据转换为具体多少小时
	public int getCycleDataToHouse(String unit,int cycleValue) {
		int totalHouse = 0;
		switch (unit) {
		case "hour":
			totalHouse = cycleValue;
			break;
		case "day":
			totalHouse = cycleValue * 24;
			break;
		case "week":
			totalHouse = cycleValue * 7 * 24;
			break;
		case "month":
			totalHouse = cycleValue * 30 * 24;
			break;
		case "quarter":
			totalHouse = cycleValue * 3 * 30 * 24;
			break;
		case "year":
			totalHouse = cycleValue * 12 * 30 * 24;
			break;
		default:
			throw new RuntimeException("传入数据无法转换时间！");
		}
		return totalHouse;
	}
}

